package com.yeskery.nut.http.bio;

import com.yeskery.nut.core.NutException;
import com.yeskery.nut.core.ServerContext;
import com.yeskery.nut.core.ServerRequestConfiguration;
import com.yeskery.nut.core.SessionManager;
import com.yeskery.nut.http.BaseRequest;
import com.yeskery.nut.util.IOUtils;

import java.io.IOException;
import java.io.InputStream;
import java.net.InetSocketAddress;
import java.net.Socket;

/**
 * 基于 <b>BIO</b> 模式下的 {@link com.yeskery.nut.core.Request} 的实现，该类继承自 {@link BaseRequest}
 * @author sprout
 * @version 1.0
 * 2019-03-19 00:28
 *
 * @see com.yeskery.nut.core.Request
 * @see com.yeskery.nut.http.BaseRequest
 */
public class BioRequest extends BaseRequest {

	/** 用于承载数据的输入流对象 */
    protected transient InputStream inputStream;

    /** Socket对象 */
    protected transient Socket socket;

	/**
	 * 构建一个 {@link BioRequest} 对象
	 * @param socket socket对象
     * @param serverContext 服务上下文
	 * @param sessionManager session 管理器对象
     * @param serverRequestConfiguration 服务请求配置对象
	 */
	public BioRequest(Socket socket, ServerContext serverContext, SessionManager sessionManager,
                      ServerRequestConfiguration serverRequestConfiguration) {
        super(serverContext, sessionManager, serverRequestConfiguration);
        try {
            this.socket = socket;
            this.inputStream = socket.getInputStream();
        } catch (IOException e) {
            throw new NutException("An Error Occurred While Deal Request.", e);
        }
        initialize();
    }

    @Override
    protected byte[] readRequestBytes() {
        return IOUtils.readHttpByteArray(inputStream);
    }

    @Override
    public String getRemoteAddress() {
        return getRemoteInetSocketAddress().getAddress().getHostAddress();
    }

    @Override
    public String getRemoteHost() {
        return getRemoteInetSocketAddress().getHostName();
    }

    @Override
    public int getRemotePort() {
        return getRemoteInetSocketAddress().getPort();
    }

    @Override
    public String getLocalAddress() {
        return getLocalInetSocketAddress().getAddress().getHostAddress();
    }

    @Override
    public String getLocalHost() {
        return getLocalInetSocketAddress().getHostName();
    }

    @Override
    public int getLocalPort() {
        return getLocalInetSocketAddress().getPort();
    }

    /**
     * 获取远程InetSocketAddress对象
     * @return 远程InetSocketAddress对象
     */
    private InetSocketAddress getRemoteInetSocketAddress() {
        return covertInetSocketAddress(socket.getRemoteSocketAddress());
    }

    /**
     * 获取本地InetSocketAddress对象
     * @return 本地InetSocketAddress对象
     */
    private InetSocketAddress getLocalInetSocketAddress() {
        return covertInetSocketAddress(socket.getLocalSocketAddress());
    }
}
